package org.cjprods.icerupt;

import org.lwjgl.BufferUtils;
import org.lwjgl.Sys;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;

import java.io.IOException;
import java.lang.invoke.ConstantCallSite;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;

import javax.swing.text.StyledEditorKit.BoldAction;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL33.*;
import static org.lwjgl.system.MemoryUtil.*;

public class launcher
{
	GLFWErrorCallback	on_error;
	GLFWKeyCallback		on_key;
	GLFWFramebufferSizeCallback on_resize;
	
	game g;
	static float update_rate = 30;

	long window;

	public void run()
	{
		try {
			init();
			loop();
		} catch(Exception e) {
			e.printStackTrace();
		}
		glfwTerminate();
	}

	void init()
	{
		glfwSetErrorCallback(on_error = errorCallbackPrint(System.err));
		if (glfwInit() != GL_TRUE) throw new IllegalStateException("Unable to initialize GLFW");

		glfwDefaultWindowHints();
		glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
		glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

		glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

		window = glfwCreateWindow(16*40, 9*40, "Hello Tank World!", NULL, NULL);
		if (window == NULL) throw new RuntimeException("Failed to create the GLFW window");

		glfwMakeContextCurrent(window);
		glfwSwapInterval(1);
		glfwShowWindow(window);
		
	}

	void loop() throws IOException
	{
		GLContext.createFromCurrent();
		g = new game();
		g.resize(16*40, 9*40);
		key_map key_down = new key_map();
		g.update(0, key_down);
		
		glfwSetKeyCallback(window, on_key = new GLFWKeyCallback() {
			@Override
			public void invoke(long window, int key, int scancode, int action, int mods)
			{
				key_down.set(key, (action != GLFW_RELEASE));
			}
		});
		
		glfwSetFramebufferSizeCallback(window, on_resize = new GLFWFramebufferSizeCallback() {
			@Override
			public void invoke(long window, int width, int height)
			{
				g.resize(width, height);
			}
		});
		
		float last_tick = (float)glfwGetTime();		
		while (glfwWindowShouldClose(window) == GL_FALSE) {
			float update_step = 1 / update_rate;
			for (float tick = (float)glfwGetTime();
					tick > last_tick + update_step;
					last_tick += update_step)
				g.update(update_step, key_down);

			g.render();
			
			glfwSwapBuffers(window);
			glfwPollEvents();
		}
	}

	public static void main(String[] args) throws IOException
	{
		new launcher().run();
	}
}
